#include "mch.h"

#include <string.h>
#include <sys/time.h>
#include <lwip/tcp.h>
#include "mch.h"

char * reply_str = "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n";
#define TEST_HTTP_EN  0
#define TEST_TCP_EN   1
#define TEST_ACCEPT_ST 0
#define TEST_RX_ST 0


#if TEST_ACCEPT_ST
static uint32_t conn_num = 0;
#endif

#if TEST_RX_ST
static uint32_t rx_num = 0;
#endif

extern struct timeval starttime;
extern int work_rank;


void print_time(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    printf("time = %d:%d \n", (u32_t)(tv.tv_sec - starttime.tv_sec), (u32_t)tv.tv_usec);
}

void BubbleSort(unsigned char R[],int n)
{
    #if 1
    char str1[40];
    int i;
    //unsigned char temp;
    
    char *str2="012345678909865432100123456789";
    memset(str1,0,40);
    
    for(i=0;i<50;i++)
    {
        memcpy(str1,str2,30);
    }
    #endif

    #if 0
    for (i=0;i<n-1;i++ ) {
        for (j=n-2;j>=i;j--) {
                temp=R[j];
                R[j]=R[j+1];
                R[j+1]=temp;
        }
    }
    #endif
} 
static err_t  recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  u16_t len = 0;
  if (p)
    len = p->tot_len;

  tcp_recved(pcb, len);

if(p)
  BubbleSort(p->payload, len);
  //printf("the payload is %s\n",(char*)p->payload);
if(p)
 pbuf_free(p);

#if TEST_HTTP_EN
  tcp_write(pcb, reply_str, strlen(reply_str), 0);

  tcp_close(pcb);
#endif  
  err = ERR_OK;
  return err;

}


static err_t  accept_cb(void *arg, struct tcp_pcb *npcb, err_t err)
{

  //mch_printf("Server:new connection from %s:%d\n", ipaddr_ntoa(&npcb->remote_ip), npcb->remote_port);  
  //tcp_accepted(npcb);

#if TEST_ACCEPT_ST
  conn_num ++;
  if( (conn_num&0x7ff) == 0 ){
    print_time();
    printf("[%d]accept connection == %d\n", work_rank, conn_num);    
  }
#endif

  //tcp_setprio(npcb, TCP_PRIO_MIN);
  tcp_recv(npcb, recv_cb);
  /*Todo: asign this pcb to a cpu core*/

  err = ERR_OK;
  return err;
  
}


int server_init(struct ip_addr *ipaddr, u16_t port)
{
  struct tcp_pcb *pcb, *npcb;
  err_t err;

  pcb = tcp_new();
  if (!pcb)
  {
      mch_printf("tcp_new failed\n");
      return -1;
  }

  err = tcp_bind(pcb, ipaddr, port); 
  if (err != ERR_OK) 
  {
      mch_printf("tcp_bind failed\n");
      return -1;
  }

  npcb = tcp_listen(pcb);
  if (npcb == NULL)
  {
      mch_printf("tcp_listen failed\n");
      return -1;
  }

  tcp_accept(npcb, accept_cb);

  return 0;
}



